/*
 * testIsGameOver.c
 *
 *  Created on: Jan 25, 2014
 *      Author: adam
 */

/* -----------------------------------------------------------------------
 * Demonstration of how to write unit tests for dominion-base
 * Include the following lines in your makefile:
 *
 * testUpdateCoins: testUpdateCoins.c dominion.o rngs.o
 *      gcc -o testUpdateCoins -g  testUpdateCoins.c dominion.o rngs.o $(CFLAGS)
 * -----------------------------------------------------------------------
 */

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

char* getCard(int cardNo);

int main() {
    int i; //loop counter
    int j; //loop counter
    int r; //initialization variable
    int a; //testing variable for empty pile
    int b; //testing variable for empty pile
    int c; //testing variable for empty pile
    int failcount = 0; //track tests passed
    int passcount = 0; //track tests failed
    int check; //holds result returned from test function
    int seed = 1000;
    int numPlayer = 2;
    int k[10] = {adventurer, council_room, feast, gardens, mine
               , remodel, smithy, village, baron, great_hall};
    struct gameState G;
    
    printf("\nTesting function isGameOver()\n\n");
    //test boundary and valid case for province card stack
    for (i = -1; i < 2; i++){

        memset(&G, 23, sizeof(struct gameState));   // clear the game state
        r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
        G.supplyCount[province] = i;

    	//ensure no supply piles are empty to avoid skewed data
        for (j = curse; j < treasure_map + 1; j++){
        	if (j != province){
                G.supplyCount[j] = 1;
        	}
        }

           	printf("Testing Province stack with %d cards.\n", G.supplyCount[province]);

            check = isGameOver(&G);            
            printf("isGameOver returned: %d  ", check);
            if (i == 0){
                printf("Expected: 1\n");
                if (check != 1){
                    printf("TEST FAILED\n");
                    failcount++;
                }
                else{
                    printf("TEST PASSED\n");
                    passcount++;
                }
            }
            else if (i > 0){
                printf("Expected: 0\n");
                if (check != 0){
                    printf("TEST FAILED\n");
                    failcount++;
                }
                else{
                    printf("TEST PASSED\n");
                    passcount++;
                }
            }
            else if (i < 0){
                printf("Expected: -1\n");
                if (check != -1){
                    printf("TEST FAILED\n");
                    failcount++;
                }
                else{
                    printf("TEST PASSED\n");
                    passcount++;
                }
            }
            printf("\n");
    }

    //test for < 3 empty piles
    //test boundary of 2 empty piles midway through list of piles
    //test boundary 2 empty piles at beginning of list of piles
    //test boundary of 2 empty piles at end of list of piles 
    for (i = 0; i < 3; i++){

        if (i == 0){
            a = curse;
            b = estate;
            printf("Testing 2 empty piles (%s, %s) at beginning of list\n", getCard(a), getCard(b));
        }

        if (i == 1){
            a = mine;
            b = remodel;
            printf("Testing 2 empty piles (%s, %s) at middle of list\n", getCard(a), getCard(b));
        }

        if (i == 2){
            a = sea_hag;
            b = treasure_map;
            printf("Testing 2 empty piles (%s, %s) at end of list\n", getCard(a), getCard(b));
        }



        memset(&G, 23, sizeof(struct gameState));   // clear the game state
        r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
     
        //populate all supply piles
        for (j = curse; j < treasure_map + 1; j++){
            if (j != province){
                G.supplyCount[j] = 1;
            }
        }

        //empty 2 test piles
        G.supplyCount[a] = 0;
        G.supplyCount[b] = 0;


        check = isGameOver(&G);
        printf("isGameOver() returned: %d  ", check);
        printf("Expected: 0\n");

        if (check == 0){
            printf("TEST PASSED\n\n");
            passcount++;
        }
        else{
            printf("TEST FAILED\n\n");
            failcount++;
        }
        


        
        //test boundary of 3 empty piles at beginning of list of piles
        //test boundary of 3 empty piles midway through list of piles
        //test boundary of 3 empty piles at end of list of list of piles
    }

    for (i = 0; i < 3; i++){

        if (i == 0){
            a = curse;
            b = estate;
            c = duchy;
            printf("Testing 3 empty piles (%s, %s, %s) at beginning of list\n", getCard(a), getCard(b), getCard(c));
        }

        if (i == 1){
            a = mine;
            b = remodel;
            c = smithy;
            printf("Testing 3 empty piles (%s, %s, %s) at middle of list\n", getCard(a), getCard(b), getCard(c));
        }

        if (i == 2){
            a = salvager;
            b = sea_hag;
            c = treasure_map;
            printf("Testing 3 empty piles (%s, %s, %s) at end of list\n", getCard(a), getCard(b), getCard(c));
        }



        memset(&G, 23, sizeof(struct gameState));   // clear the game state
        r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
     
        //populate all supply piles
        for (j = curse; j < treasure_map + 1; j++){
            if (j != province){
                G.supplyCount[j] = 1;
            }
        }

        //empty 2 test piles
        G.supplyCount[a] = 0;
        G.supplyCount[b] = 0;
        G.supplyCount[c] = 0;


        check = isGameOver(&G);
        printf("isGameOver() returned: %d  ", check);
        printf("Expected: 1\n");

        if (check == 1){
            printf("TEST PASSED\n\n");
            passcount++;
        }
        else{
            printf("TEST FAILED\n\n");
            failcount++;
        }
    }

    if (failcount == 0){
        printf("All tests passed!\n\n");
    }
    else{
        printf("%d tests failed. %d tests passed.\n", failcount, passcount);
        printf("Review log above for details.\n\n");
    }
    

    return 0;
}


/*
 * Function to convert number to string description
 */
char* getCard(int cardNo){
    if (cardNo == curse){
        return "curse";
    }
    if (cardNo == estate){
        return "estate";
    }
    if (cardNo == duchy){
        return "duchy";
    }
    if (cardNo == province){
        return "province";
    }
    if (cardNo == copper){
        return "copper";
    }
    if (cardNo == silver){
        return "silver";
    }
    if (cardNo == gold){
        return "gold";
    }
    if (cardNo == adventurer){
        return "adventurer";
    }
    if (cardNo == council_room){
        return "council_room";
    }
    if (cardNo == feast){
        return "feast";
    }
    if (cardNo == gardens){
        return "gardens";
    }
    if (cardNo == mine){
        return "mine";
    }
    if (cardNo == remodel){
        return "remodel";
    }
    if (cardNo == smithy){
        return "smithy";
    }
    if (cardNo == village){
        return "village";
    }
    if (cardNo == baron){
        return "baron";
    }
    if (cardNo == great_hall){
        return "great_hall";
    }
    if (cardNo == minion){
        return "minion";
    }
    if (cardNo == steward){
        return "steward";
    }
    if (cardNo == tribute){
        return "tribute";
    }
    if (cardNo == ambassador){
        return "ambassador";
    }
    if (cardNo == cutpurse){
        return "cutpurse";
    }
    if (cardNo == embargo){
        return "embargo";
    }
    if (cardNo == outpost){
        return "outpost";
    }
    if (cardNo == salvager){
        return "salvager";
    }
    if (cardNo == sea_hag){
        return "sea_hag";
    }
    if (cardNo == treasure_map){
        return "treasure_map";
    }
    return "fail";
}


